#ifndef CBEAM_H
#define CBEAM_H

#include "particle.h"
#include <vector>
#include <string>

using namespace std;
class CVector3d;

class CBeam{

  public:
    CBeam();
    ~CBeam();
    void                       setBeam(double, double, double, double, double, double, double, double, double, int,double, double, double);
    void                       beamDistribution(int);
    void                       beamDistribution(string);
    void                       plotBeam( );
    void                       calRms(int diagflag=0);
    void                       calRms_lab(int diagflag=1);
    void                       outBeam(string);
    void                       setStep(double);
    void                       setEnergyS(double);
    void                       setFreq(double _dFreq)    { dFreq=_dFreq;};
    void                       setBetaS(double _dBeta)   { dBetaS=_dBeta; };
    double                     getStep()           const { return  dStep;};
    CVector3d*                 getRMSEmittance()   const { return  EmitRms;};
    CVector3d*                 getAlph()           const { return  alph;};
    CVector3d*                 getBeta()           const { return  beta;};
    CVector3d*                 getEmittance()      const { return  emittance;};
    CVector3d*                 getRmsSize()        const { return  RmsSize;};
    CVector3d*                 getAveSize()        const { return  AveSize;};
    CVector3d*                 getAveSizep()        const { return  AveSizep;};
    CVector3d*                 getRmsSizep()       const { return  RmsSizep;};
    int                        getParticleNumber() const { return  particleNumber;};
    double                     getCurrent()        const { return  current;};
    double                     getDutyFactor()     const { return  dutyFactor;};
    double                     getXMax()           const { return  dXMax*100; }
    double                     getZMax()           const { return  dZMax*100; }
    double                     getZMin()           const { return  dZMin*100; }
    double                     getBetaS()          const { return  dBetaS;    }
    double                     getYMax()           const { return  dYMax*100; }
    double                     getERms()           const { return  dERms; }
    double                     getEmitRmsXY2D()    const { return  dEmitRmsXY2D ;};
    double                     getEmitRmsPhiW()    const { return  dEmitRmsPhiW ;};
    double                     getEmitRms4D()      const { return  dEmit4D ;};
    double                     getEmitRms6D()      const { return  dEmit6D ;};
    double                     getBetaAve()        const { return  dBetaAve;};
    double                     getBetaZAve()       const { return  dBetaZAve;};
    double                     getEnergyAve()      const { return  dEnergyAve;};
    double                     getEMax()           const { return  dWmax;};
    double                     getEMin()           const { return  dWmin;};
    double                     getXpRms()          const { return  dXpRms;};
    double                     getYpRms()          const { return  dYpRms;};
    double                     getXXp()            const { return  dXPx;  };
    double                     getYYp()            const { return  dYPy;  };
    double                     getZZp()            const { return  dZPz;  };
    double                     getZRms()           const { return  dZRms;  };      //m?
    double                     getEnergyS()        const { return  dEnergyS;};
    double                     getZCenter()        const { return  dZAve; };
    int                        getGoodParticle()   const { return  GoodParticle; };
    int                        getParticleLossL()  const { return  ParticleLossLong; };
    int                        getParticleLossT()  const { return  ParticleLossTran; };
    double                     getRmax()           const { return  dRMax*100; };    //in m
		void                       DisTest();
  public:
    double                     dFreq,dWaveLength;
    std::vector<particle>      p;
		int                        diagflag;
  private:
    void                       uniformDis();
    void                       kvDis();
    void                       wbDis();
    void                       DSur();
  private:
    int                        particleNumber;
    CVector3d                  *alph;
    CVector3d                  *beta;
    CVector3d                  *emittance;
    CVector3d                  *EmitRms;
    CVector3d                  *RmsSize;
    CVector3d                  *AveSize;
    CVector3d                  *AveSizep;
    CVector3d                  *RmsSizep;
    double                     dEmit4D;                                   
    double                     dEmit6D;                                   
    int                        gridX;
    int                        gridY;
    int                        gridZ;
    double                     current;
    double                     dutyFactor;
    double                     dStep;
    //===beam parameters===================================================
    double                     dXAve,dYAve,dZAve,dRAve,dXpAve,dYpAve,dZpAve,dPhiAve; 
		double                     dPxAve,dPyAve,dPzAve,dPxRms,dPyRms,dPzRms,dXPx,dYPy,dZPz;
    double                     dXRms,dYRms,dZRms,dRRms,dXpRms,dYpRms,dZpRms,dPhiRms,dERms; 
    double                     dXXp,dYYp,dZZp,dPW; //<(x-<x>)*(xp-<xp>)>
    double                     dXMax,dYMax,dRMax,dZMin,dZMax,dWmax,dWmin;
    int                        GoodParticle,ParticleLossLong,ParticleLossTran;
    //===twiss parameters==================================================
    double                     dEmitRmsXY2D,dBetaRmsXY2D,dAlphRmsXY2D;
    double                     dEmitRmsZDelt,dBetaRmsZDelt,dAlphRmsZDelt;
    double                     dEmitRmsPhiW,dBetaRmsPhiW,dAlphRmsPhiW;
    //===synchrotron particle parameters====================================
    double                     dEnergyS,dBetaS,dEnergyAve,dBetaZAve,dBetaAve;
    //dEnergyGeo  design energy, or geometry energy;
    //dEnergyS    存储在beam->p(0)中
    //dEnergyAve  是粒子的平均能量
};
#endif
